#include "StdAfx.h"
#define _USE_MATH_DEFINES
#include "FreqADSR.h"
#include <math.h>


CFreqADSR::CFreqADSR(void)
{
	mResonBand = 0.1;
	mResonFreq = 0.00079365;
	mSource = NULL;
}


CFreqADSR::~CFreqADSR(void)
{
}

void CFreqADSR::Start( void )
{
	mTime = 0.0;
	double lBps = 1 / ( GetBPM() / 60 );
	mDecay = mDuration * 0.05 * lBps;
	mSustain = mDuration * 0.1 * lBps;
	mRelease = mDuration * 0.15 * lBps;
	mState = Attack;

	mResony1[0] = mResony1[1] = mResony2[0] = mResony2[1] = 0.0;
}

bool CFreqADSR::Generate( void )
{
	double Gain = 10.0;
	double lBps = 1 / ( GetBPM() / 60 );
	double lActual = mDuration * lBps;

	//Determine frequency to filter on.
	if ( mTime < mDecay )
	{
		mState = Attack;
	}
	else if( mTime < mSustain )
	{
		mState = Decay;
	}
	else if( mTime < mRelease )
	{
		mState = Sustain;
	}
	// Release
	else if( mTime <  lActual )
	{
		mState = Release;
	}
	else if(mTime > lActual )
	{
		return false;
	}

	double lR = 1 - mResonBand/2;
	double lCosTheta =  2 * lR * cos( 2 * M_PI * mResonFreq ) / ( 1 + lR * lR );
	double lA = (1 - (lR * lR)) * sqrt( 1 - (lCosTheta * lCosTheta));
	// Multiply Gain
	lA = Gain * lA;
	
	mFrame[0] =  lA * ( mSource->Frame(0) + (mWhiteNoise/2) );
	mFrame[0] += 2 * lR * lCosTheta * mResony1[0];
	mFrame[0] -= lR * lR * mResony2[0]; 
	mFrame[1] = mFrame[0];

	// Move the results down the queue.
	mResony2[0] = mResony1[0];
	mResony2[1] = mResony1[1];
	mResony1[0] = mFrame[0];
	mResony1[1] = mFrame[1];


	mTime += GetSamplePeriod();

	return true;
}